package com.xgst.smallscreen.http

import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.net.ConnectivityManager
import com.blankj.utilcode.util.ActivityUtils
import com.blankj.utilcode.util.GsonUtils
import com.blankj.utilcode.util.JsonUtils
import com.blankj.utilcode.util.LogUtils
import com.google.gson.JsonSyntaxException
import com.hjq.http.EasyLog
import com.hjq.http.config.IRequestHandler
import com.hjq.http.exception.CancelException
import com.hjq.http.exception.DataException
import com.hjq.http.exception.HttpException
import com.hjq.http.exception.NetworkException
import com.hjq.http.exception.NullBodyException
import com.hjq.http.exception.ResponseException
import com.hjq.http.exception.ServerException
import com.hjq.http.request.HttpRequest
import com.xgst.readbook.App
import com.xgst.readbook.http.RequestException
import okhttp3.Headers
import okhttp3.Response
import okhttp3.ResponseBody
import java.io.IOException
import java.io.InputStream
import java.lang.reflect.GenericArrayType
import java.lang.reflect.Type
import java.net.ConnectException
import java.net.UnknownHostException
import java.nio.charset.StandardCharsets

class RequestHandler : IRequestHandler {
    override fun requestSuccess(httpRequest: HttpRequest<*>, response: Response, type: Type): Any {
        if (Response::class.java == type) {
            return response
        }

        if (!response.isSuccessful) {
            val responseBody = response.body()
            val source = responseBody!!.source()
            source.request(Long.MAX_VALUE)
            val buffer = source.buffer()
            val resultString = buffer.clone().readString(StandardCharsets.UTF_8)
            throw ResponseException("code: ${response.code()}\n$resultString",response)
        }

        if (Headers::class.java == type) {
            return response.headers()
        }

        val body = response.body() ?: throw NullBodyException("ResponseBody为空")

        if (ResponseBody::class.java == type) {
            return body
        }

        // 如果是用数组接收，判断一下是不是用 byte[] 类型进行接收的
        if (type is GenericArrayType) {
            val genericComponentType = type.genericComponentType
            if (Byte::class.javaPrimitiveType == genericComponentType) {
                return body.bytes()
            }
        }

        if (InputStream::class.java == type) {
            return body.byteStream()
        }

        if (Bitmap::class.java == type) {
            return BitmapFactory.decodeStream(body.byteStream())
        }

        val text: String
        text = try {
            body.string()
        } catch (e: IOException) {
            // 返回结果读取异常
            throw DataException("body.string()异常", e)
        }

        // 打印这个 Json 或者文本
        EasyLog.printJson(httpRequest, text)

        if (String::class.java == type) {
            return text
        }

        val result: Any

        result = try {
            GsonUtils.fromJson<Any>(text, type)
        } catch (e: JsonSyntaxException) {
            // 返回结果读取异常
            throw DataException("数据解析异常", e)
        }

        val code = JsonUtils.getInt(text, "code")
        val msg = JsonUtils.getString(text, "message")

        if(code == 1){
            ActivityUtils.finishAllActivities()
            //ActivityUtils.startActivity(LoginActivity::class.java)
            throw RequestException(msg)
        }

        return if (code == 200) {
            // 代表执行成功
            result
        } else {
            throw RequestException(msg)
        }
    }

    override fun requestFail(httpRequest: HttpRequest<*>, e: Exception): Exception {
        if (e is HttpException) {
            LogUtils.i("requestFail ", e.message)
            return e
        }

        if (e is UnknownHostException) {
            val info = (App.context?.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager).activeNetworkInfo
            return if (info != null && info.isConnected) {
                ServerException("本地拦截，服务器错误", e)
            } else NetworkException("网络无法连接", e)
        }

        if (e is ConnectException) {
            return ConnectException("无法连接服务器 " + e.message)
        }

        return if (e is IOException) {
            CancelException("取消请求", e)
        } else HttpException(e.message, e)

    }
}